import parse from "html-dom-parser";
import XRegExp from "xregexp";
import {createUUID} from "./core.js";

export function parseServerTemplate(htmlString = '', {keepTag = false} = {}) {
    if (htmlString === '') {
        return htmlString
    }
    let parsed = parse(htmlString);
    let vistualMap = {};
    // console.log(parsed)
    let options = {
        level: 0,
        html: htmlString,
        meta: {},
    };

    function getHtmlFromElements(arr = []) {
        let opt = {
            html: ''
        }
        function getHtml(arr, opt) {
            arr.forEach(elem => {
                if (elem.type === 'tag') {
                    let startTag = `<${elem.name} __attr__>`
                    let attr = '';
                    let keys = Object.keys(elem.attribs);
                    // console.log('elem.attribs', elem)
                    if (keys.length > 0) {
                        keys.forEach(key => {
                            attr = attr + ` ${key}="${elem.attribs[key]}"`;
                        })
                    }
                    startTag = startTag.replace('__attr__', attr);
                    opt.html = opt.html + startTag;
                    if (elem.children) {
                        getHtml(elem.children, opt)
                    }
                    opt.html = opt.html + `</${elem.name}>`;
                }
                if (elem.type === "text") {
                    opt.html = opt.html + elem.data;
                }
            })
        }
        getHtml(arr, opt);
        return opt.html;
    }

    function transform(vistualMap, options) {
        Object.keys(vistualMap).forEach(tag => {
            try {
                let templateArr = XRegExp.matchRecursive(options.html, `<${tag}>`, `</${tag}>`, 'gi', {
                    valueNames: ['between', 'left', 'match', 'right']
                });
                templateArr.forEach((s, sindex) => {
                    if ( s.name === 'match') {
                        let html = s.value;
                        let parseds = parse(html);
                        let innerMap = {};

                        let uid = createUUID();

                        options.meta[uid] = {
                            template: s.value,
                        }

                        function childTravel(arr = [], chsopt = {}) {
                            let hasSlot = false;
                            arr.forEach(sitem => {
                                if (sitem.attribs) {
                                    let keys = Object.keys(sitem.attribs);

                                    if (keys.includes('slot')) {
                                        hasSlot = true;
                                        try {
                                            let templateArr = XRegExp.matchRecursive(html, `<block slot="`, '</block>', 'gi', {
                                                valueNames: ['between', 'left', 'match', 'right']
                                            });
                                            let matchedtemplateArr = templateArr.filter(v => v.name === 'match');

                                            if (matchedtemplateArr.length > 0) {
                                                matchedtemplateArr.forEach(child => {
                                                    if (child?.value?.startsWith(sitem.attribs.slot)) {
                                                        let truecontent = child.value.replace(sitem.attribs.slot, '');
                                                        truecontent =truecontent.slice(2, truecontent.length)
                                                        // console.log('templateArr', truecontent);
                                                        innerMap[sitem.attribs.slot] = {
                                                            template: truecontent
                                                        }
                                                    }
                                                })
                                            }
                                            else {
                                            }
                                        } catch (e) {
                                            console.log('templateArr err', e, sitem)
                                        }
                                    }
                                }
                                if (sitem.children) {
                                    childTravel(sitem.children, {first: false})
                                }
                            });
                            if (!hasSlot && chsopt.first) {
                                let defhtml = getHtmlFromElements(arr);
                                // console.log('templateArr ', defhtml);
                                innerMap.default = {
                                    template: defhtml
                                };
                            }
                        }
                        childTravel(parseds,{first: true});

                        console.log('templateArr', innerMap)
                        let t = vistualMap[tag].template.replace(/{slot\s*([^}\s]*)\s*}/g, function (m, p) {
                            if (innerMap[p]) {
                                // return parseSubHtml(innerMap[p].template)
                                return parseSubHtml(innerMap[p].template, {
                                    ...options,
                                    level: options.level + 1,
                                });
                            }
                            return ''
                        }).replace('__level__', 'level' + options.level);



                        if (templateArr[sindex - 1] && templateArr[sindex + 1]) {
                            if (!keepTag) {
                                html = templateArr[sindex - 1].value + html + templateArr[sindex + 1].value
                            }
                            else {
                                html = templateArr[sindex - 1].value + html
                                t = templateArr[sindex - 1].value.replace('>', ` __uid__="${uid}">`)  + t
                            }
                        }


                        options.html = options.html.replace(html, t)
                        console.log('templateArr', html, innerMap);
                    }
                })
            } catch (e) {

            }
        })
    }

    function parseSubHtml(subhtml = '', options = {}) {
        let parsed = parse(subhtml);
        options.html = subhtml;
        travel(parsed, options);
        transform(vistualMap, options);
        return options.html;
    }


    function travel(children = [], options) {
        children.forEach(item => {
            // console.log(item)
            if (item.name === 'vtemplate') {
                let keys = Object.keys(item.attribs);
                if ( keys.includes('name')) {
                    let regexp = new RegExp(`<\\s*vtemplate\\s*name="${item.attribs.name}"\\s*>([^]*)<\\/vtemplate\\s*>`, 'g');
                    let matchAll = options.html.matchAll(regexp);
                    let match = [... matchAll];
                    vistualMap[item.attribs.name] = {
                        template: match[0][1],
                    }
                    options.html = options.html.replace(match[0][0], '')
                }
            }

            if (item.children) {
                travel(item.children, options)
            }
        });

    }

    travel(parsed, options);
    transform(vistualMap, options)
    return {
        html: options.html,
        meta: options.meta
    }
}